package com.origin.chaos.framework.core;

import com.origin.chaos.framework.core.util.ImageUtil;
import org.springframework.util.Assert;

import java.awt.*;
import java.io.IOException;
import java.util.Arrays;

/**
 * 像素画布静态实现类
 *
 * @author: tao.ding
 * @date 2021-07-02
 */
public abstract class AbstractPixelCanvas implements PixelCanvas {

    /**
     * 画布边的最大长度
     */
    public static final int MAX_SIZE = 1000;

    /**
     * 画布默认宽
     */
    private static final int DEFAULT_WIDTH = 1000;
    /**
     * 画布默认高
     */
    private static final int DEFAULT_HEIGHT = 1000;

    /**
     * 画布ID
     */
    private final Long id;

    /**
     * 画布名称
     */
    private String name;

    /**
     * 当前画布宽
     */
    private final int width;
    /**
     * 当前画布高
     */
    private final int height;

    /**
     * 当前画布像素总数
     */
    private final int size;

    /**
     * 画布数组本地缓存
     */
    private final int[][] cacheData;

    /**
     * 两次绘画之间的间隔时间
     */
    private int paintIntervalTime;

    protected AbstractPixelCanvas(Long id, String name, int width, int height, int paintIntervalTime) {
        Assert.isTrue(id > 0, "画布ID必须大于0");
        this.id = id;
        Assert.isTrue(width > 0 && height > 0 && width <= MAX_SIZE && height <= MAX_SIZE,
                "像素画布大小 " + width + " * " + height + " 不符合要求,画布边的大小范围为[0, " + MAX_SIZE + "]");
        this.name = name;
        this.width = width;
        this.height = height;
        this.size = this.width * this.height;
        this.cacheData = new int[this.height][this.width];
        this.paintIntervalTime = paintIntervalTime;
    }

    @Override
    public Long getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void updateName(String name) {
        this.name = name;
    }

    @Override
    public int getPaintIntervalTime() {
        return this.paintIntervalTime;
    }

    @Override
    public void updatePaintIntervalTime(int paintIntervalTime) {
        this.paintIntervalTime = paintIntervalTime;
    }

    @Override
    public int getWidth() {
        return this.width;
    }

    @Override
    public int getHeight() {
        return this.height;
    }

    @Override
    public int getSize() {
        return this.size;
    }

    /**
     * 获取所有用户累计画过的点位数量
     *
     * @return 所有用户累计画过的点位数量
     */
    @Override
    public abstract long getTotalPaintedPoints();

    /**
     * 累计画过的点位数量增加 var
     *
     * @param var 准备增加的数量
     */
    @Override
    public abstract void incrPaintedPoint(long var);

    /**
     * 获取所有加入过这个画布的用户数量
     *
     * @return 所有加入过这个画布的用户数量
     */
    @Override
    public abstract long getTotalJoinedUser();

    /**
     * 将用户加入到画布中
     *
     * @param userId 用户ID
     */
    @Override
    public abstract void userJoin(long userId);

    @Override
    public void update(int hPos, int wPos, int colorRgbInt) {
        this.cacheData[hPos][wPos] = colorRgbInt;
    }

    /**
     * 初始化画布
     *
     * @param ifNewCreation 是否是新建画布，如果是，则初始化为纯白，否则从对应的数据源中加载到本地缓存中
     */
    @Override
    public abstract void init(boolean ifNewCreation);

    @Override
    public void initWithColor(Color color) {
        for (int i = 0; i < this.height; i++) {
            Arrays.fill(this.cacheData[i], color.getRGB());
        }
    }

    @Override
    public int[][] getRgbIntArray() {
        return this.cacheData;
    }

    @Override
    public String[][] getRgbHexStringArray() {
        return ImageUtil.rgbIntArrToRgbHexArr(this.cacheData);

    }

    @Override
    public byte[] getCanvasImageByteArray() {
        return ImageUtil.getBufferedImageBytes(this.cacheData);
    }

    @Override
    public abstract void flush() throws IOException;
}
